package com.example.demotype;

import java.io.Serializable;
import java.lang.reflect.*;
import java.util.List;

/**
 * @author: 迟家鑫
 * @date: 2021/1/16 18:14
 * @description:
 */
// 类型变量的上限可以为多个，必须使用&符号相连接，如下所示； 其中 & 后必须为接口
public class TypeVariableTest<T extends Number & Serializable & Comparable> {

    private List<T> list;

    private T t;

    public static void main(String[] args) throws Exception{
        // 3. 泛型的类型变量，指的是List<T>、Map<K,V>中的T,K,V等值，实际的Java类型是TypeVariableImpl（TypeVariable的子类）
        // 此外，还可以对类型变量加上extend限定，这样还会有类型变量对应的上限；
        Field list = TypeVariableTest.class.getDeclaredField("list");
        Type genericType = list.getGenericType();
        System.out.println("Type Name: " + genericType);
        System.out.println("Class Name: " + genericType.getClass().getName());
        ParameterizedType parameterizedType = (ParameterizedType) genericType;
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        System.out.println("Type Name start ...");
        for (Type actualTypeArgument : actualTypeArguments) {
            System.out.println(actualTypeArgument);
            System.out.println("Class Name: " + actualTypeArgument.getClass().getName());
        }
        System.out.println("Type Name end ...");

        Field t = TypeVariableTest.class.getDeclaredField("t");
        TypeVariable genericType1 = (TypeVariable) t.getGenericType();
        // 1. getBounds 获得该类型变量的上限，也就是泛型中 extend 右边的值，
        // 例如 Number就是类型变量T的上限；如果我们只是简单的声明了List<T>(无显式定义extends)，那么默认为Object；
        Type[] bounds = genericType1.getBounds();
        for (Type bound : bounds) {
            System.out.println(bound);
        }

        // 2 getGenericDeclaration 获取声明该类型变量实体，也就是TypeVariableTest<T>中的TypeVariableTest
        GenericDeclaration genericDeclaration = genericType1.getGenericDeclaration();
        System.out.println(genericDeclaration);

        // 3 getName 获取类型变量在源码中定义的名称
        String name = genericType1.getName();
        System.out.println(name);

    }
}
